package demo.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK动态代理示例
 */
public class JdkDynamicProxyDemo {

    // 1. 定义业务接口
    interface UserService {
        void addUser(String username);
        String getUser(String username);
    }

    // 2. 实现业务接口（真实对象）
    static class UserServiceImpl implements UserService {
        @Override
        public void addUser(String username) {
            System.out.println("添加用户: " + username);
        }

        @Override
        public String getUser(String username) {
            System.out.println("获取用户: " + username);
            return "用户-" + username;
        }
    }

    // 3. 实现InvocationHandler（代理逻辑）
    static class UserServiceInvocationHandler implements InvocationHandler {
        private final Object target; // 真实对象

        public UserServiceInvocationHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 前置处理
            System.out.println("【代理】准备执行方法: " + method.getName());
            
            // 调用真实对象的方法
            Object result = method.invoke(target, args);
            
            // 后置处理
            System.out.println("【代理】方法执行完成: " + method.getName());
            return result;
        }
    }

    public static void main(String[] args) {
        // 4. 创建真实对象
        UserService realService = new UserServiceImpl();
        
        // 5. 创建InvocationHandler，传入真实对象
        InvocationHandler handler = new UserServiceInvocationHandler(realService);
        
        // 6. 创建代理对象
        UserService proxyService = (UserService) Proxy.newProxyInstance(
                UserService.class.getClassLoader(), // 类加载器
                new Class[]{UserService.class},     // 代理接口
                handler                             // InvocationHandler
        );
        
        // 7. 通过代理对象调用方法
        proxyService.addUser("张三");
        System.out.println("----------------");
        String user = proxyService.getUser("李四");
        System.out.println("返回结果: " + user);
        
        // 打印代理类信息
        System.out.println("\n代理类名称: " + proxyService.getClass().getName());
    }
}